package edu.nxmu.supersiver.dao.impl;

import java.lang.reflect.Type;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;

import edu.nxmu.supersiver.dao.DAO;
import edu.nxmu.supersiver.utils.ReflectionUtils;

public class BaseDao<T> implements DAO<T> {
	@Autowired
	private SessionFactory sessionFactory;
	private String simpleName;
	private Type type;
	{
		simpleName = ReflectionUtils.getSimpleName(getClass());
		type = ReflectionUtils.getSuperGenericType(getClass());
	}

	public Session getCurrentSession() {
		return sessionFactory.getCurrentSession();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<T> findAll() {
		String sql = "FROM " + simpleName;
		return getCurrentSession().createQuery(sql).list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<T> findBySql(String sql, Object... objs) {
		Query query = getCurrentSession().createQuery(sql);
		for (int i = 0; i < objs.length; i++) {
			query.setParameter(i, objs[i]);
		}
		return query.list();
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public T get(int id) {
		return (T) getCurrentSession().get((Class) type, id);
	}

	@Override
	public void save(T entity) {
		getCurrentSession().saveOrUpdate(entity);
	}

	
	@Override
	public void delete(T entity) {
		getCurrentSession().delete(entity);
	}

	@Override
	public void update(T entity) {
		getCurrentSession().update(entity);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<T> getAllPage(int pageNo, int pageSize) {
		String sql = "FROM " + simpleName;
		return getCurrentSession().createQuery(sql).setFirstResult((pageNo - 1) * pageSize).setMaxResults(pageSize)
				.list();
	}

	@Override
	public int getAllRows() {
		String sql = "select count(*) from " + simpleName;
		return ((Long) getCurrentSession().createQuery(sql).uniqueResult()).intValue();
	}

	@Override
	public void deleteById(int id) {
		String sql = "delete from " + simpleName + " s where s.id = ?";
		getCurrentSession().createQuery(sql)
							.setInteger(0, id)
							.executeUpdate();
	}

	@Override
	public void deleteBySql(String hql, Object... objs) {
		Query query = getCurrentSession().createQuery(hql);
		for (int i = 0; i < objs.length; i++) {
			query.setParameter(0, objs[i]);
		}
		query.executeUpdate();
	}

}
